home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 20 / Cream of the Crop 20 (Terry Blount) (1996).iso / disk / udisk.zip / UDISK.C < prev    next >
C/C++ Source or Header  |  1996-07-13  |  7KB  |  223 lines

  1. /*
  2.             ╔════════════════════════════════════════╗
  3.             ║                UDISK                   ║
  4.             ║    Copyright (c) 1996 L.I.Williams     ║
  5.             ║          All rights reserved           ║
  6.             ║   Issue 1.0             Date: 13Jul96  ║
  7.             ╚════════════════════════════════════════╝
  8. *~    UDISK.C
  9. *~    08Jul96 Iss 1.0 Created by LIW
  10. *~    Reports disk size, space used and free
  11. *~    Use CL /AT /W4 UDISK.C to compile this file
  12. *~
  13. */
  14. /***********************************************************************
  15. * HISTORY:
  16. * Date      Iss  Who Comment
  17. * 08Jul96   1.0  LIW Created
  18. ***********************************************************************/
  19. /* Include files: */
  20. #include <stdio.h>
  21. #include <dos.h>
  22. #include <string.h>
  23. #include <process.h>
  24. #include <stdlib.h>
  25. #include <setjmp.h>
  26.  
  27. /* global variables */
  28. char            error_handler[4] = { 0xb8, 0, 0, 0xcf };
  29. union REGS      iregs, oregs;
  30. struct SREGS    segregs;
  31.  
  32. /* prototypes */
  33. void    print_size(long);
  34. void    drv_info(int);
  35. void    explain(void);
  36.  
  37. /***********************************************************************
  38. * main sorts out error handling and calls drv_info for each drive
  39. ***********************************************************************/
  40. void main(int argc, char *argv[])
  41. {
  42. int             drives;
  43. unsigned int    olderr_offset, olderr_segment;
  44. int             i;
  45.  
  46. /* initialize for error handling */
  47. iregs.x.ax = 0x3524;            /* get error handler vector     */
  48. intdosx(&iregs, &oregs, &segregs);
  49. olderr_offset = oregs.x.bx;
  50. olderr_segment= segregs.es;
  51.  
  52. segread(&segregs);              /* pick up segment registers    */
  53. iregs.x.ax = 0x2524;            /* set our error handler vector */
  54. iregs.x.dx = (unsigned int)error_handler;
  55. intdosx(&iregs, &oregs, &segregs);
  56.  
  57. /* sort out command */
  58. if (argc > 1)
  59.   {
  60.   explain();
  61.   exit(1);
  62.   }
  63.  
  64. /* determine number of logical drives in system */
  65. iregs.h.ah = 0x19;              /* get current disk             */
  66. intdos(&iregs, &oregs);
  67. iregs.h.dl = oregs.h.al;
  68. iregs.h.ah = 0x0e;              /* select disk                  */
  69. intdos(&iregs, &oregs);
  70. drives = oregs.h.al;
  71. /* this is the number of drives set by lastdrive, default 5 */
  72.  
  73. printf ("\nUDISK 1.0, Freeware, (c) 1996 L. I. Williams.\n");
  74. printf ("\n                         Disk Usage Information\n\n");
  75. printf("Drive    Volume      Total Space  Used Space   Free Space     Used%%   Free%%\n\n");
  76.  
  77. /* now output drive info */
  78. for (i = 0; i < drives; i++)
  79.   drv_info(i);
  80.  
  81. printf("\
  82. \n\
  83. /? for help. (1k=1000 not 1024  1m=1,000,000 not 1,048,576)\n\
  84. ");
  85.  
  86. /* restore vector for error handling */
  87. iregs.x.ax = 0x2524;            /* get error handler vector     */
  88. oregs.x.dx = olderr_offset;
  89. segregs.ds   = olderr_segment;
  90. intdosx(&iregs, &oregs, &segregs);
  91. exit(0);
  92. }
  93.  
  94. /***********************************************************************
  95. drv_info. Information for each drive if present
  96. ***********************************************************************/
  97. void drv_info(int drive)
  98. {
  99. long            total, free, used;
  100. double          percent;
  101. struct find_t find;
  102. int found;
  103. char *p;
  104. int  i;
  105. char spec[20];
  106. char ch;
  107. struct diskfree_t drvinfo;
  108.  
  109. /*
  110. Try to print the statistics.  When a non-existant drive is read the
  111. operating system calls its fatal error handler (via INT 24h).  This
  112. has been redirected and returns, this routine returns too, and the
  113. drive is skipped.
  114. */
  115. if (_dos_getdiskfree( drive+1, &drvinfo )!=0)
  116.   return;
  117.  
  118. total = (long)drvinfo.total_clusters * 
  119.         (long)drvinfo.sectors_per_cluster *
  120.         (long)drvinfo.bytes_per_sector;
  121.  
  122. free = (long)drvinfo.avail_clusters *
  123.        (long)drvinfo.sectors_per_cluster *
  124.        (long)drvinfo.bytes_per_sector;
  125.  
  126. used  = total - free;
  127.  
  128. /* Output disk letter. numeric 0 = drive A */
  129. printf("  %c:   ", drive + 'A');
  130.  
  131. /* Scan files in root directory of disk for one with volume id
  132. attribute. It's name is the disk label. Find first matching file,
  133. then find additional matches. */
  134. sprintf(spec,"%c:\\*.*",drive + 'A');    /* pathname of root */
  135. found = !_dos_findfirst( spec, 0xffff, &find );    /* first file name */
  136. while (found)
  137.   {
  138.   if ( find.attrib & _A_VOLID )    /* is it the volume id ? */
  139.     break;            /* yes, leave loop */
  140.   found = !_dos_findnext( &find );    /* no, try another */
  141.   }
  142. *spec = '\0';            /* preset null string */
  143. if (found)            /* did we get it ? */
  144.   {
  145.   p = spec;            /* yes, copy name, ommiting '.' character */
  146.   for (i=0;i<=14;i++)
  147.     {
  148.     ch = find.name[i];
  149.     if (ch != '.')
  150.       *p++=ch;            /* copy non '.' characters */
  151.     if (ch == '\0')        /* stop after null */
  152.       break;
  153.     }
  154.   }
  155.  
  156. printf( "%-13s",spec);    /* output name or null to 13 spaces */ 
  157.  
  158. print_size(total);
  159.  
  160. print_size(used);
  161.  
  162. print_size(free);
  163.  
  164. percent = (double)used / (double)total * 100.0;
  165. printf(" %5.0f%%  ", percent);
  166.  
  167. percent = (double)free / (double)total * 100.0;
  168. printf("%5.0f%%\n", percent);
  169.  
  170. /* Try to deal with CDROM, network drives etc.  This does not work if
  171. there is no CD in the drive, so commented out.
  172. iregs.h.ah = 0x44;   determine if unusual drive
  173. iregs.h.al = 0x09;
  174. iregs.h.bl = drive +1;
  175. intdos(&iregs,&oregs);
  176. if (oregs.x.dx & 0x1000)
  177.   {
  178.   sprintf(spec,"vol %c:",drive + 'A');
  179.   system(spec);
  180.   printf("\n");
  181.   }
  182. */
  183. }
  184.  
  185. /***********************************************************************
  186. prints a disk size in a sensible way
  187. ***********************************************************************/
  188. void print_size(long n)
  189. {
  190. if      (n >= 10000000)               /* 10m or more */
  191.   printf("%7.0fm  ",(double)n/1000000.0);
  192. else if (n >= 1000000)                /* 1m to 10m */
  193.   printf("%7.1fm  ",(double)n/1000000.0);
  194. else if (n >= 10000)                  /* 10k to 999k */
  195.   printf("%7.0fk  ",(double)n/1000);
  196. else                                  /* < 10k */
  197.   printf("%7ld   ",n);
  198. printf("   ");
  199. }
  200.  
  201. /***********************************************************************
  202. Help output
  203. ***********************************************************************/
  204. void explain(void)
  205. {
  206. char filebuf[80];
  207.  
  208. _searchenv( "MORE.COM", "PATH", filebuf );
  209. if (*filebuf)
  210.   {
  211.   _searchenv( "UDISK.DOC", "PATH", filebuf );
  212.   if (*filebuf)
  213.     {
  214.     system("type UDISK.DOC | more");
  215.     exit(0);
  216.     }
  217.   }
  218. printf("See the documentation file 'UDISK.DOC' for more information.\n");
  219. }
  220. /***********************************************************************
  221. End of code
  222. ***********************************************************************/
  223.